#pragma once

#include "D3DInterface.h"
#include <d3dx9mesh.h>

namespace rubik
{
	const int FACE_RED = 0;
	const int FACE_YELLOW = 1;
	const int FACE_GREEN = 2;
	const int FACE_WHITE = 3;
	const int FACE_BLUE = 4;
	const int FACE_ORANGE = 5;
	const int FACE_DEFAULT = 6;//default is black

	const int TRIANGLECOUNT = 12;
	const int CUBECOUNT = 27;

	enum
	{
		LOCK_NULL = 0,
		LOCK_RIGHT,
		LOCK_LEFT,
		LOCK_DOWN,
		LOCK_TOP,
		LOCK_BACK,
		LOCK_FRONT
	};

	struct Vertex
	{
		Vertex(){}
		Vertex(float x, float y, float z,
			float nx, float ny, float nz)
		{
			_x = x; _y = y; _z = z;
			_nx = nx; _ny = ny; _nz = nz;
		}
		float _x, _y, _z, _nx, _ny, _nz;

		static const DWORD FVF;
	};

	struct FaceColor
	{
		int right;
		int left;
		int down;
		int top;
		int back;
		int front;
		int below;//from high to low bit, right'left'down'top'back'front, ex: 0x10101000 means the cube below to right-down-back
	};

	class CCube
	{
	public:
		CCube(void);
		~CCube(void);

		bool CreateCube(IDirect3DDevice9* device);
		bool ColorFace(FaceColor* color);
		void DrawCube(DWORD attribute);

	public:
		ID3DXMesh* m_pMesh;
		int m_iBelow;
	};

	class CRubik : public IFramework
	{
	public:
		CRubik(IDirect3DDevice9 **p);
		virtual ~CRubik(void);

		void LockFace();
		void RotateFace(D3DXMATRIX *pRotate, float time, CCube* pCube, float xAngle, float yAngle);

		// Interface
	public:
		virtual bool Setup();
		virtual bool Display(float timeDelta);
		virtual void Cleanup();

	private:
		IDirect3DDevice9 *m_pDevice;
		CCube* m_pCube[CUBECOUNT];
		D3DXMATRIX m_TransMatrix[CUBECOUNT];

		int m_iLockFace;
		int m_iRotateCount[6];
	};
}